#ifndef __HASH_TABLE_H__
#define __HASH_TABLE_H__

/* shamlessly stolean from http://www.sf.net/projects/sandiaportals/ */

#include <stdint.h>
#include <errno.h>

#include "sysy_conf.h"
#include "configure.h"
#include "mem_hugepage.h"

enum {
        HTABLE_ALLOC_YMALLOC,
        HTABLE_ALLOC_HUGE,
};

typedef uint32_t (*key_func)(const void *);
typedef int (*compare_func)(const void *, const void *);

typedef int (*malloc_func)(void **ptr, size_t size, void *ctx);
typedef int (*free_func)(void **ptr, void *ctx);

typedef struct hashtable_entry {
        uint32_t key;
        void *value;
        struct hashtable_entry *next;
} *hashtable_entry_t;

typedef struct hashtable {
        char name[MAX_NAME_LEN];
        unsigned int size;
        unsigned int num_of_entries;

        int alloc_type;
        key_func key_f;
        compare_func compare_f;

        malloc_func entry_malloc_f;
        free_func entry_free_f;
        void *ring_pool;

        hashtable_entry_t *entries;
} *hashtable_t;

hashtable_t hash_create_table(compare_func compare_f, key_func key_f, const char *name);
hashtable_t hash_create_table2(compare_func compare_f, key_func key_f, const char *name, int alloc_type);
hashtable_t hash_create_table_huge(compare_func compare_f, key_func key_f, const char *name);

void hash_destroy_table(hashtable_t, void (*thunk)(void *));

void *hash_table_find(hashtable_t, const void *comparator);
int hash_table_insert(hashtable_t, void *value, void *comparator,
                             int overwrite);
int hash_table_remove(hashtable_t, const void *comparator, void **value);

int hash_iterate_table_entries(hashtable_t tab, int (*handler)(void *, void *),
                                      void *arg);
void hash_filter_table_entries(hashtable_t, int (*handler)(void *, void *),
                                      void *arg, void (*thunk)(void *));
int hashtable_resize(hashtable_t t, int size);
int hashtable_size(hashtable_t t);


#endif
